package com.xishu.controller;

import com.xishu.client.EmailClient;
import com.xishu.config.Config;
import com.xishu.entity.Company;
import com.xishu.entity.NameAndId;
import com.xishu.entity.User;
import com.xishu.entity.area.Area;
import com.xishu.entity.plat.GuideConfig;
import com.xishu.entity.plat.PrivilegeMapping;
import com.xishu.entity.plat.UserShopMapping;
import com.xishu.entity.shop.*;
import com.xishu.response.ResponseData;
import com.xishu.response.VerifyUtil;
import com.xishu.service.*;
import com.xishu.task.InitTask;
import com.xishu.util.Sha256Util;
import com.xishu.util.Tools;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;
import java.util.stream.Collectors;

import static com.xishu.config.Constant.PRIVILEGE_SHOP_LEVEL;

/**
 * 向导配置,不提供删除接口
 */
@Api(description = "向导配置,不提供删除接口")
@RestController
public class GuideConfigController implements Tools {
    private static Logger logger = LoggerFactory.getLogger(GuideConfigController.class);
    private CommonService commonService = CommonService.getInstance();

    /**
     * 创建向导配置
     *
     * @param guideConfig
     * @return
     */
    @ApiOperation(value = "创建向导配置")
    @PostMapping(value = ("/guide/config"), produces = ("application/json;charset=UTF-8"))
    public ResponseData create(@RequestBody GuideConfig guideConfig) throws Exception {
        return commonService.createObject(guideConfig);
    }

    /**
     * 查询向导配置
     *
     * @param guideConfig
     * @return
     */
    @PutMapping(value = ("/guide/config"), produces = ("application/json;charset=UTF-8"))
    public ResponseData query(@RequestBody GuideConfig guideConfig) throws Exception {
        return commonService.searchResponse(guideConfig);
    }

    @ApiOperation(value = "修改向导配置")
    @PutMapping(value = ("/guide/config/modify"), produces = ("application/json;charset=UTF-8"))
    public ResponseData modify(@RequestBody GuideConfig guideConfig) throws Exception {
        VerifyUtil.verify(() -> guideConfig.getId() != null);
        GuideConfig guideConfigInDb = commonService.findEntity(guideConfig.getId(), GuideConfig.class);
        Boolean submit = guideConfig.getSubmit();
        Boolean submitInDb = guideConfigInDb.getSubmit();

        return commonService.updateObject(guideConfig, (g) -> {
            try {
                GuideConfig guideConfigAfterModify = commonService.findEntity(g.getId(), GuideConfig.class);
                //如果是提交操作，并且数据库里面是未提交的状态，那么执行初始化
                if (getBoolean(submit) && !getBoolean(submitInDb)) {
                    init(guideConfigAfterModify);
                }
            } catch (Exception e) {
                logger.error("e", e);
            }
        });
    }

    /**
     * 初始化配置
     *
     * @param guideConfig
     */
    public void init(GuideConfig guideConfig) throws Exception {
        logger.info("guide config is {}", guideConfig);

        Long userId = guideConfig.getUserId();

        Company company = CompanyService.getInstance().findCompanyByUserId(userId);

        //校验
        VerifyUtil.verify(() -> isNotEmpty(guideConfig.getSceneEntityList()));

        //如果不关联当前账号，那么强制校验邮件地址信息
        if (getInt(guideConfig.getManagerOptionSelect()) == 2) {
            VerifyUtil.verify(() -> isNotEmpty(guideConfig.getInviteEmail()));
        }

        VerifyUtil.verify(() -> isNotEmpty(guideConfig.getCatalogName()));

        //商铺
        Shop shop = createShop(guideConfig, company);
        //创建场景
        createSceneList(guideConfig, shop);
        //创建分类
        Catalog catalog = createCatalog(guideConfig, shop);
        updateServiceFeeConfig(guideConfig, shop);
        createItem(guideConfig, shop, catalog);
        //创建运营模式
        ShopService.getInstance().createRunModel(shop.getId());
        //迁移商铺的配置到场景下面
        InitTask.getInstance().migrateConfigToScene(shop);

        //最后邀请注册，或者关联当前账号成经理账号
        createUserCompanyMapping(guideConfig, shop, company);

        //最后发送邮件给support@dolatechnology.com
        sendEmailToSupport(guideConfig);
    }

    /**
     * 创建分店
     *
     * @param guideConfig
     * @param company
     * @return
     * @throws Exception
     */
    private Shop createShop(GuideConfig guideConfig, Company company) throws Exception {
        //创建分店
        Shop shop = new Shop();
        shop.setCompanyId(company.getId());
        shop.setCompanyName(company.getName());
        String shopName = guideConfig.getShopName();
        shop.setName(shopName);
        shop.setName_zh(shopName);
        shop.setName_en(shopName);

        shop.setShopAddress(StringUtils.join(guideConfig.getAddressList(), ","));
        shop.setShopAddress_zh(StringUtils.join(guideConfig.getAddressList(), ","));
        shop.setShopAddress_en(StringUtils.join(guideConfig.getAddressList(), ","));

        shop.setShopDetailAddress(guideConfig.getShopDetailAddress());
        shop.setShopDetailAddress_zh(guideConfig.getShopDetailAddress());
        shop.setShopDetailAddress_en(guideConfig.getShopDetailAddress());

        shop.setPhone(guideConfig.getPhone());

        //创建餐厅
        commonService.createObject(shop);
        logger.info("shop is {}", shop);
        return shop;
    }

    /**
     * 创建场景
     *
     * @param guideConfig
     * @return
     */
    private List<Scene> createSceneList(GuideConfig guideConfig, Shop shop) throws Exception {
        List<Scene> sceneList = guideConfig.getSceneEntityList();

        for (Scene scene : sceneList) {
            scene.setCompanyId(shop.getCompanyId());
            scene.setShopId(shop.getId());
            scene.setEntity(true);
            scene.setId(null);
            scene.setShopName(shop.getName());
            scene.setEnable(true);
            commonService.createObject(scene);
        }

        return sceneList;
    }

    /**
     * 创建场景的序列号
     *
     * @param guideConfig
     * @return
     */
    private Map<Integer, Scene> createSceneMap(GuideConfig guideConfig) {
        HashMap<Integer, Scene> map = new HashMap<>();
        List<Integer> sceneIndex = guideConfig.getSceneIndex();

        int index = 0;
        for (Scene scene : guideConfig.getSceneEntityList()) {
            map.put(sceneIndex.get(index), scene);
            index = index + 1;
        }

        return map;
    }

    /**
     * 创建品类
     *
     * @param guideConfig
     * @param shop
     * @return
     */
    private Catalog createCatalog(GuideConfig guideConfig, Shop shop) throws Exception {
        String catalogName = guideConfig.getCatalogName();
        Catalog catalog = new Catalog();
        catalog.setName(catalogName);
        catalog.setName_zh(catalogName);
        catalog.setName_en(catalogName);

        catalog.setCompanyId(shop.getCompanyId());
        catalog.setShopId(shop.getId());
        catalog.setShowOrder(1l);

        //如果只配置了一个场景，那么就选择该场景作为品类的场景
        if (guideConfig.getSceneEntityList().size() == 1) {
            Scene scene = guideConfig.getSceneEntityList().get(0);
            NameAndId nameAndId = new NameAndId(scene.getId(), scene.getName());
            ArrayList<NameAndId> nameAndIds = new ArrayList<>();
            nameAndIds.add(nameAndId);

            catalog.setSceneList(nameAndIds);
        } else {
            //过滤后处理
            Map<Integer, Scene> sceneMap = createSceneMap(guideConfig);

            List<String> catalogSceneIndexList = guideConfig.getCatalogSceneList();
            List<Scene> catalogSceneList = catalogSceneIndexList.stream().map(p -> sceneMap.get(Integer.parseInt(p))).collect(Collectors.toList());

            List<NameAndId> nameAndIdList = catalogSceneList.stream().map(scene -> {
                return new NameAndId(scene.getId(), scene.getName());
            }).collect(Collectors.toList());
            catalog.setSceneList(nameAndIdList);
        }

        ZhEnService.getInstance().dealZhEn(catalog);
        commonService.createObject(catalog);
        return catalog;
    }

    /**
     * 创建菜品
     *
     * @param guideConfig
     * @param shop
     * @param catalog
     * @return
     */
    private Item createItem(GuideConfig guideConfig, Shop shop, Catalog catalog) throws Exception {
        logger.info("catalog is {}", catalog);
        Item item = new Item();
        String itemName = guideConfig.getItemName();
        item.setName(guideConfig.getItemName());

        item.setCompanyId(shop.getCompanyId());
        item.setShopId(shop.getId());
        item.setSetMenu(false);
        item.setSuggestion(false);
        item.setOnline(true);
        item.setShowOrder(1);

        //清空菜品的id，因为这里肯定不是套餐
        for (ItemDetail itemDetail : guideConfig.getItemDetailList()) {
            itemDetail.setItemId(null);
        }
        item.setItemDetailList(guideConfig.getItemDetailList());

        Map<Integer, Scene> sceneMap = createSceneMap(guideConfig);
        List<String> itemSceneList = guideConfig.getItemSceneList();
        List<PriceConfig> priceConfigList = guideConfig.getPriceConfigList();

        int index = 0;
        for (PriceConfig priceConfig : priceConfigList) {
            String sceneIndex = itemSceneList.get(index);
            Scene scene = sceneMap.get(Integer.parseInt(sceneIndex));
            priceConfig.setSceneId(scene.getId());
        }

        //创建主菜，如果主菜不存在，那么创建一个
        CompanyMainItem companyMainItem = CustomerService.getInstance().getOrCreateCompanyMainItem(shop.getCompanyId(), item.getName(),  0);
        item.setMainItemId(companyMainItem.getId());

        item.setPriceConfigList(priceConfigList);
        item.setPrintAlias(guideConfig.getPrintAlias());
        ItemService.getInstance().dealItemZhEn(item);
        item.setCatalogId(catalog.getId());
        item.setCatalogName(catalog.getName());
        item.setCatalogName_zh(catalog.getName_zh());
        item.setCatalogName_en(catalog.getName_en());
        commonService.createObject(item);

        //创建映射关系
        CatalogItemMapping catalogItemMapping = new CatalogItemMapping();
        catalogItemMapping.setItemId(item.getId());
        catalogItemMapping.setItemName(itemName);
        catalogItemMapping.setItemName_zh(itemName);
        catalogItemMapping.setItemName_en(itemName);

        catalogItemMapping.setCatalogId(catalog.id);
        catalogItemMapping.setCatalogName(catalog.getName());
        catalogItemMapping.setCatalogName_zh(catalog.getName_zh());
        catalogItemMapping.setCatalogName_en(catalog.getName_en());
        catalogItemMapping.setOnline(true);
        catalogItemMapping.setShopId(shop.getId());
        catalogItemMapping.setSetMenu(false);
        catalogItemMapping.setSuggestion(false);
        ZhEnService.getInstance().dealZhEn(catalogItemMapping);

        commonService.createObject(catalogItemMapping);

        return item;
    }

    /**
     * 更新服务费比例
     *
     * @param guideConfig
     * @param shop
     */
    private void updateServiceFeeConfig(GuideConfig guideConfig, Shop shop) throws Exception {
        shop.setServiceFeePercent(guideConfig.getServiceFeePercent());
        shop.setTakeoutFeePercent(guideConfig.getTakeoutFeePercent());

        if (shop.getShopConfig() == null) {
            shop.setShopConfig(new ShopConfig());
        }

        shop.getShopConfig().setAllowAddTable(guideConfig.getAllowAddTable());
        shop.setShopId(shop.getId());
        commonService.updateObject(shop);
    }

    /**
     * 创建个人与公司之间的映射关系
     *
     * @param guideConfig
     */
    private void createUserCompanyMapping(GuideConfig guideConfig, Shop shop, Company company) throws Exception {
        if (getInt(guideConfig.getManagerOptionSelect()) == 1 || getInt(guideConfig.getManagerOptionSelect()) == 3) {
            logger.info("user select current user to manager");
            Long userId = guideConfig.getUserId();
            User user = commonService.findEntity(userId, User.class);
            user.setShopManager(true);
            Long companyId = shop.getCompanyId();
            logger.info("the company id is {}", companyId);
            user.setCompanyId(companyId);
            commonService.updateObject(user);

            //如果二级密码存在，设置二级密码
            if (isNotEmpty(guideConfig.getSecondaryPassword())) {
                logger.info("will set secondary password");
                String secondaryPassword = guideConfig.getSecondaryPassword();
                String salt = Sha256Util.generateSalt();
                secondaryPassword = Sha256Util.sha256(secondaryPassword, salt);
                user.setSecondaryPassword(secondaryPassword);
                user.setSecondarySalt(salt);
            }


            logger.info("will create user shop mapping");
            //添加账号与分店之间的映射关系
            UserShopMapping userShopMapping = new UserShopMapping();
            userShopMapping.setUserId(userId);
            userShopMapping.setShopId(shop.getId());
            userShopMapping.setShopName(shop.getName());
            userShopMapping.setUserName(user.getName());
            commonService.createObject(userShopMapping);

            //给这个,查询默认权限是否存在，如果存在，则用默认名称
            PrivilegeMapping privilegeMapping = new PrivilegeMapping();
            privilegeMapping.setDefaultPrivilege(true);
            privilegeMapping.setName("Default Permission");
            privilegeMapping.setLevel(PRIVILEGE_SHOP_LEVEL);
            privilegeMapping.setCompanyId(companyId);
            //将用户的权限写到分店权限里面去
            privilegeMapping.setPrivilegeList(new ArrayList<>());
            commonService.createObject(privilegeMapping);

            //再把创建好的权限，写到用户的privilegeList里面
            List<String> shopPrivilegeList = new ArrayList<>();
            shopPrivilegeList.add(privilegeMapping.getId() + "");
            logger.info("set user privilege list is {}", StringUtils.join(shopPrivilegeList, ","));
            user.setShopPrivilegeList(shopPrivilegeList);

            //更新用户的权限
            commonService.save(user);
        } else {
            logger.info("user invite other user to the manager");
            //只是发送邮件
            ArrayList<Long> shopIdList = new ArrayList<>();
            shopIdList.add(shop.getId());
            UserService.getInstance().inviteManager(guideConfig.getInviteEmail(), shopIdList, null, company.getLang());
        }
    }

    /**
     * 发送邮件通知dola
     *
     * @param guideConfig
     */
    private void sendEmailToSupport(GuideConfig guideConfig) throws Exception {
        Config config = Config.getInstance();
        String guideResultImage = guideConfig.getGuideResultImage();
        String endPoint = config.getProductBucketEndpoint();
        String imgUrl = String.format("https://%s/%s", endPoint, guideResultImage);

        String content = String.format("<!DOCTYPE html>\n" +
                "<html lang=\"en\">\n" +
                "<head>\n" +
                "    <meta charset=\"UTF-8\">\n" +
                "    <title>Title</title>\n" +
                "</head>\n" +
                "<body>\n" +
                "        <img src=\"%s\">\n" +
                "</body>\n" +
                "</html>", imgUrl);

        if (config.isAliyun()) {
            EmailClient.getInstance().sendEmail("1074672212@qq.com", "用户已完成向导", content);
        } else {
            EmailClient.getInstance().sendEmail("support@dolatechnology.com", "用户已完成向导", content);
        }
    }
}
